﻿using Quartz;
using Quartz.Impl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Jmit.Deyi.AutoTask.DataSync
{
	public class QuartzManage
	{
		static Task<IScheduler> task_scheduler = StdSchedulerFactory.GetDefaultScheduler();
		static IScheduler scheduler;
		private static readonly object objlock = new object();
		static QuartzManage()
		{
			if (scheduler == null)
			{
				lock (objlock)
				{
					if (scheduler == null)
					{
						scheduler = task_scheduler.Result;
						scheduler.Start();
					}
				}
			}
		}

		/// <summary>
		/// 以Simple开始一个工作
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="name"></param>
		/// <param name="simpleInterval"></param>
		public static void StartJobWithSimple<T>(string name, Action<SimpleScheduleBuilder> simpleInterval) where T : IJob
		{
			IJobDetail job = JobBuilder.Create<T>().WithIdentity(name + "_job", name + "_group").Build();
			ITrigger Simple = TriggerBuilder.Create().StartNow()
							   .WithSimpleSchedule(simpleInterval)
							   .Build() as ISimpleTrigger;

			scheduler.ScheduleJob(job, Simple);
		}

		/// <summary>
		/// 以Cron开始一个工作
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="name"></param>
		/// <param name="CronExpression"></param>
		public static void StartJobWithCron<T>(string name, string CronExpression) where T : IJob
		{

			IJobDetail job = JobBuilder.Create<T>().WithIdentity(name + "_job", name + "_group").Build();

			ITrigger CronTrigger = TriggerBuilder.Create().StartNow().WithIdentity(name + "_trigger", name + "_group")
									.WithCronSchedule(CronExpression, w => w.WithMisfireHandlingInstructionDoNothing())
									.Build() as ICronTrigger;

			scheduler.ScheduleJob(job, CronTrigger);
		}

		/// <summary>
		/// 這種辦法可以根據job名稱找到觸發器，也可以找到Job，這樣就可以在任何地方修改Job頻次，不再限於IJob的實現方法Execute內
		/// 以此實現了：即時修改執行頻次即時生效
		/// </summary>
		/// <param name="cronExpression"></param>
		/// <param name="name"></param>
		public static async void ModifyJob(string cronExpression, string name)
		{
			//触发器的key
			TriggerKey triggerKey = new TriggerKey(name + "_trigger", name + "_group");
			ITrigger trigger = await scheduler.GetTrigger(triggerKey);

			CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.CronSchedule(cronExpression);
			trigger = trigger.GetTriggerBuilder().WithIdentity(triggerKey).WithSchedule(scheduleBuilder).Build();

			await scheduler.RescheduleJob(triggerKey, trigger);
		}

		/// <summary>
		/// 删除Job，即時刪除，不再限於IJob的實現方法Execute內
		/// </summary>
		/// <param name="job"></param>
		/// <param name="trigger"></param>
		public static void DeleteJob(string name)
		{
			//触发器的key
			TriggerKey triggerKey = new TriggerKey(name + "_trigger", name + "_group");
			//Job的Key
			JobKey jobKey = new JobKey(name + "_job", name + "_group");
			scheduler.PauseTrigger(triggerKey);//暫停觸發器
			scheduler.UnscheduleJob(triggerKey);//移除觸發器
			scheduler.DeleteJob(jobKey);
		}

		/// <summary>
		/// 删除Job
		/// </summary>
		/// <param name="job"></param>
		/// <param name="trigger"></param>
		public static void DeleteJob(IJobDetail job, ITrigger trigger)
		{
			scheduler.PauseTrigger(trigger.Key);//暫停觸發器
			scheduler.UnscheduleJob(trigger.Key);//移除觸發器
			scheduler.DeleteJob(job.Key);
		}

		/// <summary>
		/// 停止運行
		/// </summary>
		public static void ShutDownJob()
		{
			if (scheduler != null && !scheduler.IsShutdown)
			{
				scheduler.Shutdown();
			}
		}
	}
}
